package core;

import java.io.IOException;

import javax.ejb.EJBException;
import javax.ejb.Stateless;

import model.Item;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.jboss.annotation.ejb.LocalBinding;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

@Stateless
@LocalBinding(jndiBinding="local/Geocoder")
public class Geocoder implements GeocoderLocal{
	private static final String URL = "http://maps.google.com/maps/api/geocode/json";
	
	public Item geocodeItem(Item item) throws HttpException, JSONException, IOException{
		if(item.getStreet() != null && item.getState() != null && item.getCity() != null && item.getCountry() != null){
			String address = item.getStreet() + ", " + item.getCity() + ", " + item.getCountry();
			
			Double[] coord = googleGeocode(address);
			item.setLatitude(coord[0]);
			item.setLongitude(coord[1]);
		}
		return item;
	}
	
	private Double[] googleGeocode(String address) throws JSONException, HttpException, IOException{
		HttpClient httpClient = new HttpClient();
		GetMethod httpMethod = new GetMethod();
		httpMethod.setPath(URL);
		NameValuePair[] parameters = new NameValuePair[2];
		parameters[0] = new NameValuePair("address", address);
		parameters[1] = new NameValuePair("sensor", "false");
		httpMethod.setQueryString(parameters);
		
		int statusCode = httpClient.executeMethod(httpMethod);
		if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_NOT_FOUND) {
			throw new EJBException("Unexpected Http Status Code: " + statusCode + ". Response Body: " + httpMethod.getResponseBodyAsString() );
		}
		
        String  response = httpMethod.getResponseBodyAsString();
        
        double lat = 0;
        double lng = 0;
        
		if (!"".equals(response)) {
            JSONObject json = new JSONObject(response);
            if (json.has("results")) {
                JSONArray jsonArray = (JSONArray) json.get("results");
                if (jsonArray != null && jsonArray.length() > 0) {
                    JSONObject jsonFirstResult = jsonArray.getJSONObject(0);
                    if (jsonFirstResult.has("geometry")) {
                        JSONObject jsonGeometry = jsonFirstResult.getJSONObject("geometry");
                        if (jsonGeometry.has("location")) {
                            JSONObject jsonLocation = jsonGeometry.getJSONObject("location");
                            if (jsonLocation.has("lat") && jsonLocation.has("lng")) {
                                lat = jsonLocation.getDouble("lat");
                                lng = jsonLocation.getDouble("lng");
                            }
                        }
                    }
                }
            }
        }
		
		Double[] result = {lat, lng};
		return result;
	}
}
